package sketch.generator;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import sketch.generator.examples.ExhaustiveSequatialValueGenerator;

public class ExhaustiveValueGenerator<T> extends ValueGenerator<T> {
	
	private final ExhaustiveSequatialValueGenerator<T> innerGenerator;
	
	public ExhaustiveValueGenerator(T... values) {
		super();
		innerGenerator = new ExhaustiveSequatialValueGenerator<T>(values);
	}
	
	public ExhaustiveValueGenerator(List<T> values) {
		super();
		innerGenerator = new ExhaustiveSequatialValueGenerator<T>(values);
	}
	
	public List<T> currentValue() {
		return this.innerGenerator.current().getValues();
	}
	
	public boolean hasNextValues() {
		return this.innerGenerator.hasNext();
	}
	
	public List<T> nextValue() {
		return this.innerGenerator.next().getValues();
	}
	
	public List<List<T>> allValues() {
		List<List<T>> listOfList = new LinkedList<List<T>>();
		this.reset();
		while(this.hasNextValues()) {
			listOfList.add(this.nextValue());
		}
		this.reset();
		return listOfList;
	}
	
	//public int Exhaustive
	
	@Override
	public void reset() {
		super.reset();
		this.innerGenerator.reset();
	}

	/**
	 * This is not a good design, since it break the unified interface when generating
	 * the  next available data.
	 * */
	@Override
	public T composeData() {
		throw new UnsupportedOperationException("Compose data not implemented" +
		" in ExhaustiveValueGenerator");
	}

	@Override
	protected T generateNext() {
		throw new UnsupportedOperationException("generate next not implemented" +
		" in ExhaustiveValueGenerator");
	}

	@Override
	public boolean hasNext() {
//		throw new UnsupportedOperationException("has next not implemented" +
//		" in ExhaustiveValueGenerator");
		return this.hasNextValues();
	}

	@Override
	public List<T> nextWrappedValue() {
		return this.nextValue();
	}

}
